package mips.instructions;

/**
 * <code>SYNC</code> instruction<br/>
 * Synchronize</br>
 * @author jnmartin84@gmail.com
 */
public class SYNC extends Instruction {

	private static final String INSTRUCTION_NAME = "SYNC";
	private static SYNC INSTANCE = new SYNC();

	private SYNC(){}

	public static final SYNC getInstance() {
		return INSTANCE;
	}

	/**
	 * <b>Format:</b><br/>
	 * SYNC<br/><br/>
	 * <b>Description:</b><br/>
	 * The SYNC instruction ensures that any loads and stores fetched prior to the<br/>
	 * present instruction are completed before any loads or stores after this<br/>
	 * instruction are allowed to start. Use of the SYNC instruction to serialize<br/>
	 * certain memory references may be required in a multiprocessor<br/>
	 * environment for proper synchronization.<br/><br/>
	 * For processors which only execute loads and stores in order, with respect<br/>
	 * to shared memory, this instruction is a NOP.<br/><br/>
	 * LL and SC instructions implicitly perform a SYNC.<br/><br/>
	 * This instruction is allowed in User mode.<br/><br/>
	 * <b>Operation:</b><br/>
	 * T: SyncOperation()<br/>
	 */
	@Override
	public final void execute(final int instruction){
 
		mips.R4300i.PC = mips.R4300i.nPC;
		mips.R4300i.nPC = mips.R4300i.PC + 4;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String emit(final int instruction) {
		return	"		mips.CPU.PC = mips.CPU.nPC;\n" + 
				"		mips.CPU.nPC = mips.CPU.PC + 4;\n";
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName(final int instruction) {
		return getName();
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName() {
		return INSTRUCTION_NAME;
	}
}